﻿//*********************************************************************
//
//  文件名：CollectInvoiceService
//
//  作者： Pwp
//
//  作用：收票服务器处理类
//
//  日期：2015-10-08
//
//*********************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YouTravel.DomainModels;
using YouTravel.Framework.Const;
using YouTravel.Framework.Enums;
using YouTravel.QueryModels;
using YouTravel.ViewModels;
using System.Data.Entity;
using Framework.Common.Exceptions;
using YouTravel.Framework.ResourceMessage;
using IRepositories.Core;
using EntityFramework.Data.Core;
using Framework.Common.Paged;
using Framework.Common;

namespace YouTravel.DomainService
{
	public class CollectInvoiceService : ICollectInvoiceService
	{
		readonly IEFRepository<Payment> _paymentRepository;
		readonly IEFRepository<CollectInvoice> _collectinvoiceRepository;
		readonly IEFRepository<CollectInvoiceGroup> _collectinvoicegroupRepository;
		readonly IEFRepository<CollectInvoiceDetail> _collectinvoicedetailRepository;
		readonly IEFRepository<InvoiceSubject> _invoicesubjectRepository;
		readonly IEFRepository<Special> _specialRepository;


		readonly IUnitOfWork _db;
		public CollectInvoiceService(IUnitOfWork db, IEFRepository<Payment> paymentRepository, IEFRepository<CollectInvoice> collectinvoiceRepository
			, IEFRepository<CollectInvoiceGroup> collectinvoicegroupRepository, IEFRepository<CollectInvoiceDetail> collectinvoicedetailRepository
			, IEFRepository<InvoiceSubject> invoicesubjectRepository, IEFRepository<Special> specialRepository)
		{
			this._db = db;
			this._collectinvoiceRepository = collectinvoiceRepository;
			this._collectinvoiceRepository.SetDbContext(this._db);
			this._paymentRepository = paymentRepository;
			this._paymentRepository.SetDbContext(this._db);
			this._collectinvoicegroupRepository = collectinvoicegroupRepository;
			this._collectinvoicegroupRepository.SetDbContext(this._db);
			this._collectinvoicedetailRepository = collectinvoicedetailRepository;
			this._collectinvoicedetailRepository.SetDbContext(this._db);
			this._invoicesubjectRepository = invoicesubjectRepository;
			this._invoicesubjectRepository.SetDbContext(this._db);
			this._specialRepository = specialRepository;
			this._specialRepository.SetDbContext(this._db);
		}

		/// <summary>
		/// 机构列表页面 Pwp 2015-09-16
		/// </summary>
		/// <param name="queryCond"></param>
		/// <returns></returns>
		public CustomPagedList<CollectInvoiceViewModel> GetList(PagedParam<CollectInvoiceQuery> queryCond)
		{
			return _paymentRepository.GetModel(o => o.Status == PaymentStatus.HasPayment)
				.Include(o => o.SellerSupplier)
				.Include(o => o.Special)
				.Include(o => o.CollectInvoice)
				.GetPagedList(queryCond.PageDto.PageNo,
				queryCond.PageDto.PageSize, BuildQueryCondition(queryCond.QueryDto),
				queryCond.SortField).ToCustomPagedList<Payment, CollectInvoiceViewModel>((u) =>
				{
					var s = u.MapNew<Payment, CollectInvoiceViewModel>();
					s.SupplyName = u.SellerSupplier.Name;
					if (u.CollectInvoice != null && u.CollectInvoice.Count > 0)
					{
						CollectInvoice c = u.CollectInvoice.OrderByDescending(o => o.CreateTime).FirstOrDefault();
						s.CollectInvoiceStatus = (int)c.Status;
						s.ConfirmTime = c.CreateTime;
					}
					else
					{
						s.CollectInvoiceStatus = (int)CollectInvoiceQueryStatus.NotSubmit;
					}
					return s;
				});
		}

		/// <summary>
		/// 查询条件处理
		/// </summary>
		/// <param name="branchQuery"></param>
		/// <returns></returns>
		private Func<IQueryable<Payment>, IQueryable<Payment>> BuildQueryCondition(CollectInvoiceQuery collectinvoiceQuery)
		{
			return (query) =>
			{
				if (collectinvoiceQuery != null)
				{
					if (collectinvoiceQuery.SpecialId != 0)
					{
						query = query.Where(p => p.SpecialId == collectinvoiceQuery.SpecialId);
					}
					if (collectinvoiceQuery.BranchId != 0)
					{
						query = query.Where(p => p.Special.BranchId == collectinvoiceQuery.BranchId);
					}
					if (!string.IsNullOrEmpty(collectinvoiceQuery.Name))
					{
						query = query.Where(p => p.Special.Name.Contains(collectinvoiceQuery.Name) || p.Special.ChargeName.Contains(collectinvoiceQuery.Name));
					}
					if (collectinvoiceQuery.Role == 2)
					{
						if (collectinvoiceQuery.Type != 0)
						{
							query = query.Where(p => p.CollectInvoice.OrderByDescending(o => o.CreateTime).FirstOrDefault().Status == (CollectInvoiceStatus)collectinvoiceQuery.Type);
						}
						else
						{
							query = query.Where(p => p.CollectInvoice.Count > 0);
						}
					}
					else
					//if(collectinvoiceQuery.Role == 1)
					{
						if (collectinvoiceQuery.Type != 0)
						{
							if (collectinvoiceQuery.Type == (int)CollectInvoiceQueryStatus.NotSubmit)
							{
								query = query.Where(p => p.CollectInvoice.Count < 1);
							}
							else
							{
								query = query.Where(p => p.CollectInvoice.OrderByDescending(o => o.CreateTime).FirstOrDefault().Status == (CollectInvoiceStatus)collectinvoiceQuery.Type);
							}
						}
					}
					if (collectinvoiceQuery.StartData.HasValue)
					{
						DateTime start = collectinvoiceQuery.StartData.Value.Date;
						query = query.Where(p => p.AuditTime >= start);
					}
					if (collectinvoiceQuery.EndData.HasValue)
					{
						DateTime end = collectinvoiceQuery.EndData.Value.AddDays(1).Date;
						query = query.Where(p => p.AuditTime < end);
					}
				}
				return query;
			};
		}

		/// <summary>
		/// 提交发票 Pwp 2015-10-08
		/// </summary>
		/// <param name="contractview"></param>
		/// <returns></returns>
		public void AddCollectInvoice(CollectInvoiceAddModel contractview)
		{
			Payment mPayment = _paymentRepository.GetModel(o => o.ID == contractview.PaymentID).FirstOrDefault();
			if (mPayment.Money > contractview.Money)
				throw new BusinessException(string.Format(BusinessResourceMessage.ItemComparison, "付款金额", "收票金额"));
			//付款发票
			CollectInvoice mCollectInvoice = new CollectInvoice();
			mCollectInvoice.PaymentId = contractview.PaymentID;
			mCollectInvoice.Status = CollectInvoiceStatus.WaitVerify;
			mCollectInvoice.Remark = contractview.Remark;
			mCollectInvoice.CreaterId = contractview.OperatorID;
			mCollectInvoice.CreateTime = contractview.OptionTime;

			TransactionScopeNoMsdtc.UsingTransactionNoMsdtc(_db, () =>
			{
				_collectinvoiceRepository.Insert(mCollectInvoice);
				foreach (CollectInvoiceAddModelGroup tempGroup in contractview.Group)
				{
					CollectInvoiceGroup mCollectInvoiceGroup = new CollectInvoiceGroup();
					mCollectInvoiceGroup.CollectInvoiceId = mCollectInvoice.ID;
					mCollectInvoiceGroup.GroupCode = tempGroup.Code;
					mCollectInvoiceGroup.Name = tempGroup.Name;
					_collectinvoicegroupRepository.Insert(mCollectInvoiceGroup);
					foreach (CollectInvoiceAddModelInfo tempInfo in tempGroup.Info)
					{
						CollectInvoiceDetail mCollectInvoiceDetail = new CollectInvoiceDetail();
						mCollectInvoiceDetail.CollectInvoiceId = mCollectInvoice.ID;
						mCollectInvoiceDetail.GroupId = mCollectInvoiceGroup.ID;
						mCollectInvoiceDetail.Code = tempInfo.Code;
						mCollectInvoiceDetail.Money = tempInfo.Money;
						mCollectInvoiceDetail.Date = tempInfo.Date;
						mCollectInvoiceDetail.Content = tempInfo.Content;
						_collectinvoicedetailRepository.Insert(mCollectInvoiceDetail);
					}
				}
			});
		}

		/// <summary>
		/// 获取机构信息 Pwp 2015-10-08
		/// </summary>
		/// <param name="paymentId">付款ID</param>
		/// <returns></returns>
		public CollectInvoiceDetailModel DetailCollectInvoice(int paymentId)
		{
			bool isInvoiceSubjectType = Convert.ToBoolean((int)InvoiceSubjectType.BackInvoice);
			bool isInvoiceSubjectStatus = Convert.ToBoolean((int)InvoiceSubjectStatus.Normal);

			//付款信息表
			Payment mPayment = _paymentRepository.GetModel(o => o.ID == paymentId)
				.Include(o => o.SellerSupplier)
				.Include(o => o.Special).FirstOrDefault();
			if (mPayment == null)
				throw new BusinessException(string.Format(BusinessResourceMessage.ItemNotFound, "付款信息"));
			List<InvoiceSubjectDetail> mInvoiceSubject = (from p in _invoicesubjectRepository.GetModel(o => o.BranchId == mPayment.Special.BranchId)
														  where p.Type == isInvoiceSubjectType && p.Status == isInvoiceSubjectStatus
														  select new InvoiceSubjectDetail
														  {
															  ID = p.ID,
															  Name = p.InvoiceSubjectName
														  }).ToList();
			//付款收票对应所有团
			List<CollectInvoiceGroup> lstGroup = new List<CollectInvoiceGroup>();
			//付款收票对应所有发票
			List<CollectInvoiceDetail> lstDetail = new List<CollectInvoiceDetail>();
			//付款收票信息
			CollectInvoice mCollectInvoice = (from p in _collectinvoiceRepository.GetModel()
											  where p.PaymentId == paymentId
											  select p)
							  .Include(o => o.Creater)
							  .OrderByDescending(p => p.CreateTime)
							  .FirstOrDefault();
			if (mCollectInvoice != null)
			{
				//付款收票对应所有团
				lstGroup = (from p in _collectinvoicegroupRepository.GetModel()
							where p.CollectInvoiceId == mCollectInvoice.ID
							select p).ToList();
				//付款收票对应所有发票
				lstDetail = (from p in _collectinvoicedetailRepository.GetModel()
							 where p.CollectInvoiceId == mCollectInvoice.ID
							 select p).ToList();
			}

			List<CollectInvoiceAddModelGroup> lstAddGroup = new List<CollectInvoiceAddModelGroup>();
			if (lstGroup != null)
			{
				CollectInvoiceAddModelGroup mCollectInvoiceAddModelGroup = null;
				foreach (CollectInvoiceGroup tempGroup in lstGroup)
				{
					mCollectInvoiceAddModelGroup = new CollectInvoiceAddModelGroup();
					mCollectInvoiceAddModelGroup.ID = tempGroup.ID;
					mCollectInvoiceAddModelGroup.Code = tempGroup.GroupCode;
					mCollectInvoiceAddModelGroup.Name = tempGroup.Name;
					List<CollectInvoiceAddModelInfo> lstAddInfo = new List<CollectInvoiceAddModelInfo>();
					List<CollectInvoiceDetail> lstGroupDetail = lstDetail.Where(o => o.GroupId == tempGroup.ID).ToList();
					if (lstGroupDetail != null)
					{
						CollectInvoiceAddModelInfo mCollectInvoiceAddModelInfo = null;
						foreach (CollectInvoiceDetail tempDetail in lstGroupDetail)
						{
							mCollectInvoiceAddModelInfo = new CollectInvoiceAddModelInfo();
							mCollectInvoiceAddModelInfo.ID = tempDetail.ID;
							mCollectInvoiceAddModelInfo.Code = tempDetail.Code;
							mCollectInvoiceAddModelInfo.Date = tempDetail.Date;
							mCollectInvoiceAddModelInfo.Money = tempDetail.Money;
							mCollectInvoiceAddModelInfo.Content = tempDetail.Content;
							lstAddInfo.Add(mCollectInvoiceAddModelInfo);
						}
					}
					mCollectInvoiceAddModelGroup.Info = lstAddInfo;
					lstAddGroup.Add(mCollectInvoiceAddModelGroup);
				}
			}

			CollectInvoiceDetailModel mCollectInvoiceDetailModel = new CollectInvoiceDetailModel();
			if (mCollectInvoice != null)
			{
				mCollectInvoiceDetailModel.ID = mCollectInvoice.ID;
				mCollectInvoiceDetailModel.Submit = mCollectInvoice.Creater.Name;
				mCollectInvoiceDetailModel.SubmitTime = mCollectInvoice.CreateTime;
				mCollectInvoiceDetailModel.Confirm = mCollectInvoice.UpdaterName;
				mCollectInvoiceDetailModel.ConfirmTime = mCollectInvoice.UpdateTime;
				mCollectInvoiceDetailModel.ConfirmRemark = mCollectInvoice.Remark;
			}
			else
			{
				mCollectInvoiceDetailModel.ID = 0;
			}
			mCollectInvoiceDetailModel.PaymentID = mPayment.ID;
			mCollectInvoiceDetailModel.SpecialId = mPayment.SpecialId;
			mCollectInvoiceDetailModel.SpecialName = mPayment.SpecialName;
			mCollectInvoiceDetailModel.SupplyId = mPayment.SellerSupplier.ID;
			mCollectInvoiceDetailModel.SupplyName = mPayment.SellerSupplier.Name;
			mCollectInvoiceDetailModel.Money = mPayment.Money;
			mCollectInvoiceDetailModel.Remark = mPayment.Remark;
			mCollectInvoiceDetailModel.Group = lstAddGroup;
			mCollectInvoiceDetailModel.InvoiceSubject = mInvoiceSubject;

			return mCollectInvoiceDetailModel;
		}

		/// <summary>
		/// 修改付款发票状态
		/// </summary>
		/// <param name="collectinvoicemodel"></param>
		public void EditCollectInvoiceStatus(CollectInvoiceStatusModel collectinvoicemodel)
		{
			///付款收票表
			CollectInvoice mCollectInvoice = _collectinvoiceRepository.GetModelTracking()
				.Include(o => o.Payment)
				.Include(o => o.Payment.Special)
				.Include(o => o.Payment.Special.SpecialCapital)
				.Where(o => o.ID == collectinvoicemodel.ID)
				.FirstOrDefault();
			if (mCollectInvoice == null)
				throw new BusinessException(string.Format(BusinessResourceMessage.ItemNotFound, "收票信息"));
			SpecialCapital mTempSpecialCapital = mCollectInvoice.Payment.Special.SpecialCapital;

			//付款收票对应所有发票
			var lstDetail = (from p in _collectinvoicedetailRepository.GetModel()
							 where p.CollectInvoiceId == mCollectInvoice.ID
							 select p).ToList();
			///发票总金额
			decimal deMoney = lstDetail.Sum(o => o.Money);
			///收票
			if (collectinvoicemodel.Status == CollectInvoiceStatus.HasCollectInvoice)
			{
					//_collectinvoiceRepository.Update(x => x.ID == collectinvoicemodel.ID, u => new CollectInvoice
					//{
					//	Status = collectinvoicemodel.Status,
					//	Remark = collectinvoicemodel.Remark,
					//	UpdaterId = collectinvoicemodel.OperatorID,
					//	UpdaterName = collectinvoicemodel.OperatorName,
					//	UpdateTime = collectinvoicemodel.OptionTime
					//});
					mCollectInvoice.Status = collectinvoicemodel.Status;
					mCollectInvoice.Remark = collectinvoicemodel.Remark;
					mCollectInvoice.UpdaterId = collectinvoicemodel.OperatorID;
					mCollectInvoice.UpdaterName = collectinvoicemodel.OperatorName;
					mCollectInvoice.UpdateTime = collectinvoicemodel.OptionTime;
					mCollectInvoice.Payment.Special.SpecialCapital.InvoiceCollect += deMoney;
					mCollectInvoice.Payment.Special.UpdaterId = collectinvoicemodel.OperatorID;
					mCollectInvoice.Payment.Special.UpdaterName = collectinvoicemodel.OperatorName;
					mCollectInvoice.Payment.Special.UpdateTime = collectinvoicemodel.OptionTime;
					_collectinvoiceRepository.Update(mCollectInvoice);
					//SpecialCapital mSpecialCapital = new SpecialCapital();
					//mSpecialCapital.InvoiceCollect = mSpecialCapital.InvoiceCollect + deMoney;
					//_specialRepository.Update(x => x.ID == mCollectInvoice.Payment.SpecialId, u => new Special
					//{
					//	SpecialCapital = mSpecialCapital,
					//	UpdaterId = collectinvoicemodel.OperatorID,
					//	UpdaterName = collectinvoicemodel.OperatorName,
					//	UpdateTime = collectinvoicemodel.OptionTime
					//});
			}
			else
			{
				_collectinvoiceRepository.Update(x => x.ID == collectinvoicemodel.ID, u => new CollectInvoice
				{
					Status = collectinvoicemodel.Status,
					Remark = collectinvoicemodel.Remark,
					UpdaterId = collectinvoicemodel.OperatorID,
					UpdaterName = collectinvoicemodel.OperatorName,
					UpdateTime = collectinvoicemodel.OptionTime
				});
			}
		}
	}
}